using System;
using ServiceStack;
using ServiceStack.Redis;
using ServiceStack.Redis.Generic;
using ServiceStack.ServiceInterface;
using System.Collections.Generic;

using GameTools;

using PuSuoPai;

namespace DTFight
{
	public class DTFightService : Service
	{
		//================================= Login =================================
		public RoomInfoListRsp Post(GetRoomInfoListRqt request)
		{
			RoomInfoListRsp rsp = null;

			try {
				List<int> roomInfos = new List<int>();
				for (int i=1; i<=GameMgr.ROOM_COUNT; ++i)
				{
					roomInfos.Add(GameMgr.Instance.GetRoom(i).PlayerCount);
				}

				rsp = new RoomInfoListRsp();
				rsp.RoomInfoList = roomInfos;
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public GameHistory Post(EnterRoomRqt request)
		{
			GameHistory rsp = null;

			try {
				var redis = RedisMgr.Instance.GetClient ().As<Player> ();
				Player curPlayer = redis.GetFromHash(request.Name);
				if (curPlayer == null)
				{
					return null;
				}

				PlayerData player = new PlayerData();
				player.PlayerId = request.Name;
				player.Points = (UInt32)curPlayer.Points;

				GameMgr.Instance.ExitRoom(request.Name);

				if (!GameMgr.Instance.EnterRoom(request.RoomId, player))
				{
					return null;
				}

				GameData room = GameMgr.Instance.GetRoom(request.RoomId);

				Console.WriteLine(DateTime.Now.ToString() + "$$" + string.Format("[{0}]进入房间！", request.Name));

				GameHistory gh = new GameHistory();
				gh.ResultList = room.ResultList;
				rsp = gh;
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public ResultResponse Post(ExitRoomRqt request)
		{
			ResultResponse rsp = null;

			try {
				GameMgr.Instance.ExitRoom(request.Name);

				Console.WriteLine(DateTime.Now.ToString() + "$$" + string.Format("[{0}]离开房间！", request.Name));

				ResultResponse rt = new ResultResponse();
				rt.Result = "ok";
				rsp = rt;
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public GetRankingInRoomRsp Post(GetRankingInRoomRqt request)
		{
			GetRankingInRoomRsp rsp = null;

			try {
				GameData room = GameMgr.Instance.GetRoom(request.Name);
				if (room == null)
					return null;

				rsp = new GetRankingInRoomRsp();
				rsp.Ranking = room.RankingInRoom;
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public GetRoomStateRsp Post(GetRoomStateRqt request)
		{
			GetRoomStateRsp rsp = null;

			try {
				GameData room = GameMgr.Instance.GetRoom(request.Name);
				if (room == null)
					return null;

				rsp = new GetRoomStateRsp();
				rsp.CurStateInfo = room.CurStateInfo;

				rsp.DesktopCards = new List<byte>();
				for (int i=0; i<room.DesktopCards.Length; ++i)
				{
					if (room.DesktopCards[i] != null)
						rsp.DesktopCards.Add(room.DesktopCards[i].CardId);
					else
						rsp.DesktopCards.Add(0);
				}
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public GameData.ResultInfo Post(GetGameResultRqt request)
		{
			GameData.ResultInfo rsp = null;

			try {
				GameData room = GameMgr.Instance.GetRoom(request.Name);
				if (room == null)
					return null;

				if (room.ResultList.Count <= 0)
					return null;

				if (room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.OPEN_CARD_7
					&& room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.SHOW_BET_RESULT)
				{
					return null;
				}

				rsp = new GameData.ResultInfo();
				rsp = room.ResultList[room.ResultList.Count - 1];
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public GameData.PlayerBetResult Post(GetBetResultRqt request)
		{
			GameData.PlayerBetResult rsp = null;

			try {
				GameData room = GameMgr.Instance.GetRoom(request.Name);
				if (room == null)
					return null;

				if (room.ResultList.Count <= 0)
					return null;

				GameData.ResultInfo rt = room.ResultList[room.ResultList.Count - 1];
				foreach (var info in rt.PlayerBetResults)
				{
					if (info.PlayerId.Equals(request.Name))
					{
						rsp = info;
						break;
					}
				}
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public SelectAdviserRsp Post(SelectAdviserRqt request)
		{
			SelectAdviserRsp rsp = null;

			try {

				PlayerData player = GameMgr.Instance.GetPlayer(request.Name);
				if (player == null)
					return null;

				GameData room = GameMgr.Instance.GetRoom(player.CurRoomId);
				if (room == null)
					return null;

				if (room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.SELECT_GROUP)
				{
					return null;
				}

				GameData.ADVISER_TYPE adviserType = (GameData.ADVISER_TYPE)request.AdviserType;

				UInt32 needPoint = 10;
				if (adviserType == GameData.ADVISER_TYPE.拉斯维加斯)
					needPoint = 20;
				else if (adviserType == GameData.ADVISER_TYPE.澳门)
					needPoint = 15;

				if (player.Points < needPoint)
				{
					return null;
				}

				player.Points -= needPoint;

				GameData.GROUP_TYPE group = room.QueryAdviser(adviserType);

				// save db
				var redis = RedisMgr.Instance.GetClient ().As<Player> ();
				Player curPlayer = redis.GetFromHash(request.Name);
				if (curPlayer == null)
				{
					return null;
				}

				curPlayer.Points = (int)player.Points;
				redis.StoreAsHash(curPlayer);

				SelectAdviserRsp rt = new SelectAdviserRsp();
				rt.GroupId = (UInt32)group;
				rt.Points = (int)player.Points;

				rsp = rt;
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public SelectAdviserRsp Post(BetPlayerRqt request)
		{
			SelectAdviserRsp rsp = null;

			try {
				PlayerData player = GameMgr.Instance.GetPlayer(request.Name);
				if (player == null)
					return null;

				PlayerData betPlayer = GameMgr.Instance.GetPlayer(request.PlayerName);
				if (betPlayer == null)
					return null;

				if (betPlayer.CurRoomId != player.CurRoomId)
					return null;

				GameData room = GameMgr.Instance.GetRoom(player.CurRoomId);
				if (room == null)
					return null;

				if (room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.SELECT_GROUP)
				{
					return null;
				}

				if (player.Points < 10)
				{
					return null;
				}

				player.FollowBetPalyer = request.PlayerName;

				player.Points -= 10;

				// save db
				var redis = RedisMgr.Instance.GetClient ().As<Player> ();
				Player curPlayer = redis.GetFromHash(request.Name);
				if (curPlayer == null)
				{
					return null;
				}

				curPlayer.Points = (int)player.Points;
				redis.StoreAsHash(curPlayer);

				SelectAdviserRsp rt = new SelectAdviserRsp();
				rt.GroupId = (UInt32)room.GetPlayerGroup(betPlayer);
				rt.Points = (int)player.Points;

				rsp = rt;
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public SelectGroupRsp Post(SelectGroupRqt request)
		{
			SelectGroupRsp rsp = null;

			try {
				var redis = RedisMgr.Instance.GetClient ().As<Player> ();
				Player curPlayer = redis.GetFromHash(request.Name);
				if (curPlayer == null)
				{
					return null;
				}

				PlayerData player = GameMgr.Instance.GetPlayer(request.Name);
				if (player == null)
					return null;

				player.Points = (UInt32)curPlayer.Points;

				GameData room = GameMgr.Instance.GetRoom(request.Name);
				if (room == null)
					return null;

				if (room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.SELECT_GROUP)
				{
					return null;
				}

				if (curPlayer.Points < GameData.BASE_POINT)
				{
					return null;
				}

				if (room.GetPlayerGroup (player) != GameData.GROUP_TYPE.MAX)
					return null;

				GameData.GROUP_TYPE group = (GameData.GROUP_TYPE)request.GroupId;
				room.SelectGroup(player, group);

				room.BetPoint(player, GameData.BASE_POINT);
				//player.Points -= GameData.BASE_POINT;
				//player.BetPoints[2] += GameData.BASE_POINT;
				curPlayer.Points -= (int)GameData.BASE_POINT;

				// save db
				redis.StoreAsHash(curPlayer);

				SelectGroupRsp rt = new SelectGroupRsp();
				rt.Points = curPlayer.Points;
				rsp = rt;
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}

		public BetPointRsp Post(BetPointRqt request)
		{
			BetPointRsp rsp = null;

			try {
				var redis = RedisMgr.Instance.GetClient ().As<Player> ();
				Player curPlayer = redis.GetFromHash(request.Name);
				if (curPlayer == null)
				{
					return null;
				}

				PlayerData player = GameMgr.Instance.GetPlayer(request.Name);
				if (player == null)
					return null;

				player.PlayerId = request.Name;
				player.Points = (UInt32)curPlayer.Points;

				GameData room = GameMgr.Instance.GetRoom(player.CurRoomId);
				if (room == null)
					return null;

				if (room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.OPEN_NONE
					&& room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.OPEN_CARD_1
					&& room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.OPEN_CARD_2
					&& room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.OPEN_CARD_3
					&& room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.OPEN_CARD_4
					&& room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.OPEN_CARD_5
					&& room.CurStateInfo.StateFlag != (UInt32)GameData.STATE_FLAG.OPEN_CARD_5)
				{
					return null;
				}

				byte rate = room.BetPoint(player, request.Point);
				if (rate == 0)
				{
					return null;
				}

				player.Points -= request.Point;

				// save db
				curPlayer.Points = (int)player.Points;
				redis.StoreAsHash(curPlayer);

				rsp = new BetPointRsp();
				rsp.Points = curPlayer.Points;
				rsp.BetPoints = new List<uint>();
				for (int i=0; i<player.BetPoints.Length; ++i)
				{
					rsp.BetPoints.Add(player.BetPoints[i]);
				}
			}
			catch (Exception e) {
				Log.WriteLog (e.Message);
			}

			return rsp;
		}
	}
}